package pl.edu.agh.ki.ewywiadowka.tests;
import static org.junit.Assert.*;

import java.util.Date;
import java.util.LinkedList;
import java.util.List;

import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;

import pl.edu.agh.ki.ewywiadowka.client.Const;
import pl.edu.agh.ki.ewywiadowka.client.EWywiadowkaService;
import pl.edu.agh.ki.ewywiadowka.client.dto.AbsenceDTO;
import pl.edu.agh.ki.ewywiadowka.client.dto.AttendantDTO;
import pl.edu.agh.ki.ewywiadowka.client.dto.ClassDTO;
import pl.edu.agh.ki.ewywiadowka.client.dto.MarkDTO;
import pl.edu.agh.ki.ewywiadowka.client.dto.StudentDTO;
import pl.edu.agh.ki.ewywiadowka.client.dto.SubjectDTO;
import pl.edu.agh.ki.ewywiadowka.client.dto.SystemUserDTO;
import pl.edu.agh.ki.ewywiadowka.client.dto.TeacherDTO;
import pl.edu.agh.ki.ewywiadowka.server.EWywiadowkaServiceImpl;


public class EWywiadowkaServiceTest {
	private EWywiadowkaService service;
	@Before
	public void setUp() throws Exception {
		service= new EWywiadowkaServiceImpl();
	}

	@Test
	public void testGetAttributesTeacher() {
		Const.Attributes attr = ((EWywiadowkaServiceImpl)service).getAttributes("nSara.Brzozkowski6","2787063754");
		assertTrue(attr == Const.Attributes.TEACHER);
	}
	
	@Test
	public void testGetAttributesUnknown() {
		Const.Attributes attr = ((EWywiadowkaServiceImpl)service).getAttributes("nAgata.Rybak","0681747528");
		assertTrue(attr == Const.Attributes.UNKNOWN);
	}
	
	@Test public void testGetAttributesStudent() {
		Const.Attributes attr = ((EWywiadowkaServiceImpl)service).getAttributes("uWojciech.Szczerbaniuk3","4436065524");
		assertEquals(Const.Attributes.STUDENT, attr);
	}

	@Ignore
	@Test public void testGetAttributesEducator() {
	//	Const.Attributes attr = ((EWywiadowkaServiceImpl)service).getAttributes("nAgata.Rybak","0681747528");
	//	assertEquals(Const.Attributes.EDUCATOR, attr);
	}
	
	@Test public void testGetAttributesAttendant() {
		Const.Attributes attr = ((EWywiadowkaServiceImpl)service).getAttributes("oSara.Wnuk26","2082560523");
		assertEquals(Const.Attributes.ATTENDANT,attr);
	}

	@Test
	public void testRegisterAndRemoveClass() {
		TeacherDTO wychowawca=service.getPotentialEducators().get(0);
		ClassDTO nk=new ClassDTO(null,new Date(1987,1,1), new Character('x'),wychowawca);
		Const.Error.ClassRegisterMsg msg=service.registerClass(nk);
		assertFalse("Błąd połączenia",msg == Const.Error.ClassRegisterMsg.CONNECTION_ERROR);
		assertFalse("Nieznany błąd",msg == Const.Error.ClassRegisterMsg.UNKNOWN);
		assertFalse("Klasa już istnieje",msg == Const.Error.ClassRegisterMsg.CLASS_ALREADY_EXISTS);
		assertEquals(Const.Error.ClassRegisterMsg.OK,msg);
		List<ClassDTO> klasy=service.getClasses();
		boolean byl=false;
		for(ClassDTO klasa : klasy) {
			if (klasa.equals(nk))
				byl=true;
		}
		assertTrue("Klasa nie zostala dodana",byl);
		List<TeacherDTO> wychowawcy=service.getPotentialEducators();
		assertFalse("Wychowawca nie zostal dobrze zaznaczony",wychowawcy.contains(wychowawca));
		Const.Error.ClassRemoveMsg msg2=service.removeClass(nk);
		assertEquals(Const.Error.ClassRemoveMsg.OK,msg2);
		byl=false;
		klasy=service.getClasses();
		for(ClassDTO klasa : klasy) {
			if (klasa.equals(nk))
				byl=true;
		}
		assertFalse("Klasa nie zostala usunieta",byl);
		wychowawcy=((EWywiadowkaServiceImpl)service).getEducators();
		assertFalse("Wychowawca nie zostal dobrze usuniety",wychowawcy.contains(wychowawca));
	}

	@Ignore
	@Test
	public void testModifyClass() {
		LinkedList<ClassDTO> klasy=service.getClasses();
		ClassDTO klasa=klasy.get(0);
		klasa.letter=new Character('r');
		Const.Error.ClassModifyMsg msg=service.modifyClass(klasa);
		LinkedList<ClassDTO> klasy2=service.getClasses();
		boolean byl=false;
		for(ClassDTO klasa2 : klasy2) {
			if(klasa2.equals(klasa))
				byl=true;
		}
		assertTrue("Zmiana sie nie powiodla",byl);
	}

	@Ignore
	@Test
	public void testGetEducators() {
		List<TeacherDTO> educators=((EWywiadowkaServiceImpl)service).getEducators();
		assertNotNull("Zwrócił nulla",educators);
		assertFalse("Lista jest pusta", educators.isEmpty());
		for(TeacherDTO educator : educators)
			assertNotNull("Wpis jest nullem", educator);
	}
	
	@Ignore
	@Test
	public void testGetPotentialEducators() {
		List<TeacherDTO> educators=service.getPotentialEducators();
		assertNotNull("Zwrócił nulla",educators);
		assertFalse("Lista jest pusta", educators.isEmpty());
		for(TeacherDTO educator : educators)
			assertNotNull("Wpis jest nullem", educator);
	}
	
	@Ignore
	@Test
	public void testGetClasses() {
		LinkedList<ClassDTO> klasy=service.getClasses();
		assertTrue("Lista klas jest pusta",klasy.size() > 0);
//		for(ClassDTO klasa : klasy)
//			System.out.println("Klasa: "+klasa);
	}
	
	@Ignore
	@Test
	public void testGetClassSquad() {
		LinkedList<ClassDTO> klasy=service.getClasses();
		LinkedList<StudentDTO> sklad=service.getClassSquad(klasy.get(3));
		assertTrue("Lista uczniow jest pusta",sklad.size() > 0);
//		for(StudentDTO uczen : sklad)
//			System.out.println("Uczen "+uczen);
	}
	
	@Ignore
	@Test
	public void testGetStudents() {
		LinkedList<StudentDTO> uczniowie=service.getStudents();
		assertTrue("Lista uczniow jest pusta",uczniowie.size() > 0);
//		for(StudentDTO uczen : uczniowie)
//			System.out.println("Uczen "+uczen);
	}
	
	@Ignore
	@Test
	public void testGetTeachers() {
		LinkedList<TeacherDTO> nauczyciele=service.getTeachers();
		assertTrue("Lista nauczycieli jest pusta",nauczyciele.size() > 0);
//		for(TeacherDTO nauczyciel : nauczyciele)
//			System.out.println("Nauczyciel "+nauczyciel);
	}
	
	@Ignore
	@Test
	public void testGetAttendants() {
		LinkedList<AttendantDTO> opiekunowie=service.getAttendants();
		assertTrue("Lista opiekunow jest pusta",opiekunowie.size() > 0);
//		for(AttendantDTO opiekun : opiekunowie)
//			System.out.println("Opiekun "+opiekun);
	}
	
	@Test
	public void testSystemUserTeacher() {
		SystemUserDTO user = service.getSystemUser("nSara.Brzozkowski6","2787063754");
		assertEquals(Const.Attributes.TEACHER, user.user.attr);
	}
	
	@Test
	public void testGetSystemUserUnknown() {
		SystemUserDTO user = service.getSystemUser("nAgata.Rybak","0681747528");
		assertEquals(Const.Attributes.UNKNOWN, user.user.attr);
	}
	
	@Test public void testGetSystemUserAttendant() {
		SystemUserDTO user = service.getSystemUser("oSara.Wnuk26","2082560523");
		assertEquals(Const.Attributes.ATTENDANT, user.user.attr);
	}
	
	@Test public void testGetSystemUserSecretary() {
		SystemUserDTO user = service.getSystemUser("sekretarka_x","abc");
		assertEquals(Const.Attributes.SECRETARY, user.user.attr);
		System.out.println(user.user.login+" "+user.user.email);
	}
	
	@Ignore
	@Test
	public void testGetSubjects() {
		LinkedList<SubjectDTO> przedmioty=service.getSubjects();
		assertTrue("Lista przedmiotów jest pusta",przedmioty.size() > 0);
//		for(SubjectDTO przedmiot : przedmioty)
//			System.out.println("Przedmiot "+przedmiot);
	}
	
	@Ignore
	@Test
	public void testGetSingleMarks() {
		StudentDTO uczen=service.getStudents().get(5);
		SubjectDTO przedmiot=service.getSubjects().get(5);
		LinkedList<MarkDTO> lista=service.getSingleMarks(uczen,przedmiot);
		assertTrue("Lista ocen jest pusta",lista.size() > 0);
//		for(MarkDTO item : lista)
//			System.out.println("Ocena "+item);
	}
	
	@Ignore
	@Test
	public void testGetFinalMark() {
		StudentDTO uczen=service.getStudents().get(5);
		SubjectDTO przedmiot=service.getSubjects().get(5);
		MarkDTO mark=service.getFinalMark(uczen, przedmiot);
		assertNotNull("Błędny obiekt oceny",mark);
//		System.out.println("Ocena końcowa: "+mark);
	}
	
	@Ignore
	@Test
	public void testRegisterAndRemoveStudent() {
		StudentDTO student=service.getStudents().get(0);
		student.numer+=1000;
		Const.Error.StudentRegisterMsg msg=service.registerStudent(student);
		assertEquals(Const.Error.StudentRegisterMsg.OK, msg);
		Const.Error.StudentRemoveMsg msg2=service.removeStudent(student);
		assertEquals(Const.Error.StudentRemoveMsg.OK,msg2);
	}
	
	@Ignore
	@Test
	public void testRegisterStudentExisting() {
		StudentDTO student=service.getStudents().get(0);
		Const.Error.StudentRegisterMsg msg=service.registerStudent(student);
		assertEquals(Const.Error.StudentRegisterMsg.STUDENT_ALREADY_EXISTS,msg);
	}
	
	@Ignore
	@Test
	public void testModifyStudent() {
		StudentDTO student=service.getStudents().get(0);
		String name=student.name;
		String surname=student.surname;
		student.name=student.name.trim()+"-modified";
		student.surname=student.surname.trim()+"-modified";
		Const.Error.StudentModifyMsg msg=service.modifyStudent(student);
		assertEquals(Const.Error.StudentModifyMsg.OK,msg);
		student.name=name;
		student.surname=surname;
		msg=service.modifyStudent(student);
		assertEquals(Const.Error.StudentModifyMsg.OK,msg);
	}
	
	@Test
	public void testRegisterAndRemoveAttendant() {
		AttendantDTO opiekun=service.getAttendants().get(0);
		opiekun.work=opiekun.work.trim()+"2";
		opiekun.user.pass="abc";
		opiekun.user.login=opiekun.user.login.trim()+"2";
		Const.Error.AttendantRegisterMsg msg=service.registerAttendant(opiekun);
		assertEquals(Const.Error.AttendantRegisterMsg.OK, msg);
		Const.Error.AttendantRemoveMsg msg2=service.removeAttendant(opiekun);
		assertEquals(Const.Error.AttendantRemoveMsg.OK,msg2);
	}
	
	@Ignore
	@Test
	public void testModifyAttendant() {
		AttendantDTO opiekun=service.getAttendants().get(0);
		String name=opiekun.name;
		String surname=opiekun.surname;
		opiekun.name=opiekun.name.trim()+"-modified";
		opiekun.surname=opiekun.surname.trim()+"-modified";
		Const.Error.AttendantModifyMsg msg=service.modifyAttendant(opiekun);
		assertEquals(Const.Error.AttendantModifyMsg.OK,msg);
		opiekun.name=name;
		opiekun.surname=surname;
		msg=service.modifyAttendant(opiekun);
		assertEquals(Const.Error.AttendantModifyMsg.OK,msg);
	}
	
	@Ignore
	@Test
	public void testModifyTeacher() {
		TeacherDTO nauczyciel=service.getTeachers().get(0);
		String name=nauczyciel.name;
		String surname=nauczyciel.surname;
		nauczyciel.name=nauczyciel.name.trim()+"-modified";
		nauczyciel.surname=nauczyciel.surname.trim()+"-modified";
		Const.Error.TeacherModifyMsg msg=service.modifyTeacher(nauczyciel);
		assertEquals(Const.Error.TeacherModifyMsg.OK,msg);
		nauczyciel.name=name;
		nauczyciel.surname=surname;
		msg=service.modifyTeacher(nauczyciel);
		assertEquals(Const.Error.TeacherModifyMsg.OK,msg);
	}
	
	@Ignore
	@Test
	public void testRegisterAndRemoveTeacher() {
		TeacherDTO nauczyciel=service.getTeachers().get(0);
		nauczyciel.surname=nauczyciel.surname.trim()+"2";
		nauczyciel.user.pass="abc";
		nauczyciel.user.login=nauczyciel.user.login.trim()+"2";
		//Const.Error.TeacherRegisterMsg msg=service.registerTeacher(nauczyciel);
		//assertEquals(Const.Error.TeacherRegisterMsg.OK, msg);
		Const.Error.TeacherRemoveMsg msg2=service.removeTeacher(nauczyciel);
		assertEquals(Const.Error.TeacherRemoveMsg.OK,msg2);
	}

	@Ignore
	@Test
	public void testAddSingleMark() {
		StudentDTO student=service.getStudents().get(1);
		LinkedList<SubjectDTO> subjects=service.getSubjects();
		int i=0;
		boolean jest=false;
		TeacherDTO teacher=null;
		LinkedList<MarkDTO> oceny=null;
		while(!jest && i<subjects.size()) {
			teacher=service.getSubjectTeacherForClass(subjects.get(i),student);
			oceny=service.getSingleMarks(student, subjects.get(i));
			if(oceny.size()>0)
				jest=true;
			i++;
		}
		if(i<subjects.size()) {
			//System.out.println("tu");
			MarkDTO ocena=oceny.get(0);
			assertTrue("Nie powiodło się dodawanie oceny",service.addSingleMark(ocena, teacher));
		}
	}
	
	@Ignore
	@Test
	public void testSetFinalMark() {
		StudentDTO student=service.getStudents().get(1);
		LinkedList<SubjectDTO> subjects=service.getSubjects();
		int i=0;
		boolean jest=false;
		TeacherDTO teacher=null;
		MarkDTO ocena=null;
		while(ocena==null && i<subjects.size()) {
			teacher=service.getSubjectTeacherForClass(subjects.get(i),student);
			ocena=service.getFinalMark(student, subjects.get(i));
			i++;
		}
		if(i<subjects.size()) {
			//System.out.println("tu");
			assertTrue("Nie powiodło się dodawanie oceny",service.setFinalMark(ocena, teacher));
		}
	}
	
	@Ignore
	@Test
	public void testRemoveSingleMark() {
		StudentDTO student=service.getStudents().get(1);
		LinkedList<SubjectDTO> subjects=service.getSubjects();
		int i=0;
		boolean jest=false;
		LinkedList<MarkDTO> oceny=null;
		while(!jest && i<subjects.size()) {
			oceny=service.getSingleMarks(student, subjects.get(i));
			if(oceny.size()>0)
				jest=true;
			i++;
		}
		if(i<subjects.size()) {
			//System.out.println("tu");
			MarkDTO ocena=oceny.get(0);
			assertTrue("Nie powiodło się usuwanie oceny",service.removeSingleMark(ocena));
		}
	}

	@Ignore
	@Test
	public void testGetAbsences() {
		StudentDTO student=service.getStudents().get(1);
		LinkedList<AbsenceDTO> nieobecnosci=service.getAbsences(student);
		assertNotNull("Zwrocil nulla",nieobecnosci);
//		for(AbsenceDTO absence : nieobecnosci)
//			System.out.println("Nieobecnosc "+absence);
	}

	@Ignore
	@Test
	public void testExcuseAbsence() {
		StudentDTO student=service.getStudents().get(1);
		AbsenceDTO nieobecnosc=service.getAbsences(student).get(0);
		assertTrue("Nie powiodlo sie usprawiedliwianie",service.excuseAbsence(nieobecnosc));
		//System.out.println(nieobecnosc.id);
	}
	
	@Ignore
	@Test
	public void testAddAbsence() {
		StudentDTO student=service.getStudents().get(1);
		AbsenceDTO nieobecnosc=service.getAbsences(student).get(0);
		assertTrue("Nie powiodlo sie dodawanie nieobecnosci",service.addAbsence(nieobecnosc)==Const.Error.AbsenceRegisterMsg.OK);
	}
}
